package cn.dogger.easyboot.netty.handler;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * @author dogger
 * 2022/11/25 18:26
 */
public class NettyServerHandler extends SimpleChannelInboundHandler<String> {

    public static final ChannelGroup CHANNEL_GROUP = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 客户端连接服务端成功后会回调该方法
     *
     * @param ctx 客户端连接通道
     * @throws Exception 异常
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //获取当前客户端的channel
        Channel channel = ctx.channel();
        CHANNEL_GROUP.writeAndFlush(new TextWebSocketFrame(channel.remoteAddress()+"已上线"));
        CHANNEL_GROUP.add(channel);
        System.out.println(channel.remoteAddress() + "已上线,当前连接数: " + CHANNEL_GROUP.size() + "\n");
    }

    /**
     * 读取客户端发送的数据
     *
     * @param ctx channel
     * @param msg 内容 ;
     * 内容类型:   TextWebSocketFrame 文本帧,
     *            BinaryWebSocketFrame 包含二进制数据
     *            ContinuationWebSocketFrame 包含属于上一个TextWebSocketFrame 或 BinaryWebSocketFrame的数据
     *            CloseWebSocketFrame 标识一个close请求,包含一个关闭的状态码
     *            PingWebSocketFrame 包含一个PongWebSocketFrame
     *            PongWebSocketFrame 作为一个对PingWebSocketFrame的响应被发送
     * @throws Exception 异常
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Channel channel = ctx.channel();
        ByteBuf buf;
        if (msg instanceof WebSocketFrame frame) {
            //如果是前端发来的信息
            buf = frame.content();
            System.out.println("服务端收到客户端" + channel.remoteAddress() + "消息:" + buf.toString(CharsetUtil.UTF_8) + "\n");
            //通过文本帧像所有人发送一条消息
            CHANNEL_GROUP.writeAndFlush(new TextWebSocketFrame("有人涉嫌黄赌毒,警告处理! "));
        }else{
            //否则就是客户端发来的
            buf = (ByteBuf) msg;
            //群发消息
            System.out.println("服务端收到客户端" + channel.remoteAddress() + "消息:" + buf.toString(CharsetUtil.UTF_8) + "\n");
            CHANNEL_GROUP.writeAndFlush("有人涉嫌黄赌毒,警告处理! ");
        }
        //遍历channel组
        for (Channel ch : CHANNEL_GROUP) {
            if (ch == channel) {
                //如果当前通话是自己,就給自己发送一条消息,说明自己发送消息了
                ch.writeAndFlush("[自己] 发送消息" + buf.toString(CharsetUtil.UTF_8) + "\n");
            } else {
                //否则就給在线用户发送一条消息说明有用户发送消息
                ch.writeAndFlush("[客户端]" + channel.remoteAddress() + "发送消息" + buf.toString(CharsetUtil.UTF_8) + "\n");
            }
        }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception {

    }

    /**
     * 客户端退出时
     *
     * @param ctx channel
     * @throws Exception 异常
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println("客户端" + channel.remoteAddress() + "已关闭,当前连接数: " + CHANNEL_GROUP.size());
    }
}
